package xfsale.service.impl.j2ee;

import java.lang.reflect.Field;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import xfsale.exception.AppException;
import xfsale.domain.SysDictItem;
import xfsale.packet.BaseRequest;
import xfsale.packet.BaseResponse;

public abstract class BaseOrder extends BaseOperation {

    private final String SERVICECODE_TRANSACCTOPEN = "1201";
    private final String SERVICECODE_TRANSACCTPASSSET = "1211";
    
    private BaseRequest request;            //服务请求
    private BaseResponse response;          //服务应答
    protected String transAcctStatus;		//交易账户状态
    protected String custAccountID;			//客户帐号
    protected String custType;				//客户类型
    protected String custName;				//客户名称
    protected String custNameAbbr;			//客户简称
    protected String nationality;			//国籍
    protected String certType;				//证件类型
    protected String certNo;				//证件号码
    protected String certValidFrom;			//证件有效期起始日期
    protected String certValidTo;			//证件有效期结束日期
    protected String businessCode;          //业务代码

    public BaseOrder(BaseRequest request, BaseResponse response) {
        super(request, response);

        this.request = request;
        this.response = response;
    }

    //初始化
    @Override
    protected void init() throws Exception {
        super.init();

        //初始化系统字典
        sys.initDict();
    }

    //检查输入参数
    @Override
    protected void checkData() throws Exception {
        super.checkData();

        //检查交易帐号
        if (!SERVICECODE_TRANSACCTOPEN.equals(request.getString("serviceCode"))) {
            if (!request.has("transAccountID")) {
                throw new AppException("请求不包括transAccountID属性");
            }
            if (!request.getString("transAccountID").matches("^[0-9]{1,10}$")) {
                throw new AppException("交易帐号不合法");
            }
        }

        //检查委托日期
        if (!response.has("orderDate")) {
            throw new AppException("应答不包括orderDate属性");
        }

        //检查委托时间
        if (!response.has("orderTime")) {
            throw new AppException("应答不包括orderTime属性");
        }

        //检查委托流水
        if (!response.has("orderSerialNo")) {
            throw new AppException("应答不包括orderSerialNo属性");
        }
    }

    //初始化
    @Override
    protected void load() throws Exception {
        super.load();

        String serviceCode = request.getString("serviceCode");
        String transAccountID = request.getString("transAccountID");
        businessCode = rule.getBusinessCode(serviceCode);

        //获取委托日期、委托时间
        response.setString("orderDate", sys.getWorkDay());
        response.setString("orderTime", sys.getWorkTime());

        if (SERVICECODE_TRANSACCTOPEN.equals(serviceCode)) {
            return;
        }

        PreparedStatement stmt = null;
        ResultSet rs = null;
        int count = 0;
        try {
            //检查交易账户是否存在
            stmt = conn.prepareStatement(""
                    + "select count(*) "
                    + "from AcctTrans "
                    + "where transAccountID = ? ");
            stmt.setString(1, transAccountID);
            rs = stmt.executeQuery();
            rs.next();
            count = rs.getInt(1);
            if (count <= 0) {
                throw new AppException("交易帐号不存在");
            }
            stmt.close();

            //获取交易账户状态、客户账户
            stmt = conn.prepareStatement(""
                    + "select transAcctStatus, custAccountID "
                    + "from AcctTrans "
                    + "where transAccountID = ? ");
            stmt.setString(1, transAccountID);
            rs = stmt.executeQuery();
            rs.next();
            transAcctStatus = rs.getString(1);
            custAccountID = rs.getString(2);
            stmt.close();

            stmt = conn.prepareStatement(""
                    + "select count(*) "
                    + "from AcctCust "
                    + "where custAccountID = ? ");
            stmt.setString(1, custAccountID);
            rs = stmt.executeQuery();
            rs.next();
            count = rs.getInt(1);
            if (count <= 0) {
                throw new AppException("客户帐号不存在");
            }
            stmt.close();

            //获取投资者类型、投资者名称、投资者简称、投资者国籍、投资者证件类型、投资者证件号码、投资者证件有效期
            stmt = conn.prepareStatement(""
                    + "select custType, custName, custNameAbbr, nationality, "
                    + "certType, certNo, certValidFrom, certValidTo "
                    + "from AcctCust "
                    + "where custAccountID = ? ");
            stmt.setString(1, custAccountID);
            rs = stmt.executeQuery();
            rs.next();
            custType = rs.getString(1);
            custName = rs.getString(2);
            custNameAbbr = rs.getString(3);
            nationality = rs.getString(4);
            certType = rs.getString(5);
            certNo = rs.getString(6);
            certValidFrom = rs.getString(7);
            certValidTo = rs.getString(8);
            stmt.close();
        } finally {
            stmt.close();
        }

        //检查经办人信息
        checkTransactor();
    }

    //检查功能权限
    @Override
    protected void checkPriv() throws Exception {
        super.checkPriv();

        String serviceCode = request.getString("serviceCode");
        if (SERVICECODE_TRANSACCTOPEN.equals(serviceCode)) {
            return;
        }

        //检查交易账户状态是否允许执行该业务
        priv.setServiceCode(serviceCode);
        priv.setTransAcctStatus(transAcctStatus);
        priv.checkAcctTrans();
    }

    //检查条件是否满足
    @Override
    protected void checkCondition() throws Exception {
        super.checkCondition();

        String serviceCode = request.getString("serviceCode");
        if (SERVICECODE_TRANSACCTOPEN.equals(serviceCode)) {
            return;
        } else if (SERVICECODE_TRANSACCTPASSSET.equals(serviceCode)) {
            return;
        }

        //检查交易密码
        checkPassword();
    }

    //写入操作日志
    @Override
    protected void writeLog() throws Exception {
        log.setOrderSerialNo(response.getString("orderSerialNo"));
        super.writeLog();
    }

    //功能处理
    @Override
    protected abstract void process() throws Exception;

    //检查交易密码
    private void checkPassword() throws Exception {
        if (!request.has("tradePassword")) {
            throw new AppException("请求不包括tradePassword属性");
        }
        if (!request.getString("tradePassword").matches("^\\S{1,64}$")) {
            throw new AppException("交易密码不合法");
        }

        String transAccountID = request.getString("transAccountID");
        String tradePassword = request.getString("tradePassword");

        PreparedStatement stmt = null;
        try {
            logger.debug("检查交易密码...");
            stmt = conn.prepareStatement(""
                    + "select count(*) "
                    + "from AcctTrans "
                    + "where transAccountID = ? "
                    + "and tradePassword = ?");
            stmt.setString(1, transAccountID);
            stmt.setString(2, tradePassword);
            ResultSet rs = stmt.executeQuery();
            rs.next();
            int count = rs.getInt(1);
            if (count <= 0) {
                throw new AppException("交易密码错误");
            }
            logger.debug("检查交易密码通过.");
        } catch (Exception e) {
            logger.error("检查交易密码出错. " + e);
            throw e;
        } finally {
            stmt.close();
        }
    }

    //检查经办人信息
    private void checkTransactor() throws Exception {
        if (custType.equals("1")) {
            return;
        }

        //检查经办人姓名
        if (!request.has("instTransName")) {
            throw new AppException("请求不包括instTransName属性");
        }
        if (!request.getString("instTransName").matches("^.+$")) {
            throw new AppException("经办人名称不合法");
        }

        //检查经办人证件类型
        if (!request.has("instTransCertType")) {
            throw new AppException("请求不包括instTransCertType属性");
        }
        if (!request.getString("instTransCertType").matches("^[0-9]$")) {
            throw new AppException("经办人证件类型不合法.");
        }

        //检查经办人证件号码
        if (!request.has("instTransCertNo")) {
            throw new AppException("请求不包括instTransCertNo属性");
        }
        if (!request.getString("instTransCertNo").matches("^([0-9Xx]{15}|[0-9Xx]{18}$")) {
            throw new AppException("经办人证件号码不合法.");
        }

        //检查经办人证件有效期起始日期
        if (!request.has("instTransCertValidFrom")) {
            throw new AppException("请求不包括instTransCertValidFrom属性");
        }
        if (!request.getString("instTransCertValidFrom").matches("^([0-9]{8})?$")) {
            throw new AppException("经办人证件有效期起始日期不合法.");
        }

        //检查经办人证件有效期截至日期
        if (!request.has("instTransCertValidTo")) {
            throw new AppException("请求不包括instTransCertValidTo属性");
        }
        if (!request.getString("instTransCertValidTo").matches("^([0-9]{8})?$")) {
            throw new AppException("经办人证件有效期截至日期不合法.");
        }
    }

    //检查是否符合数据字典的验证规则
    private void checkDict() throws Exception {
        for (Field field : request.getClass().getFields()) {
            String fieldNameUpper = field.getName().toUpperCase();
            if (sys.getDictItems().containsKey(fieldNameUpper)) {
                SysDictItem dictItem = sys.getDictItems().get(fieldNameUpper);
                if (field.getType() == String.class) {
                    String value = String.valueOf(field.get(request));
                    if (!value.matches(dictItem.itemVerify)) {
                        throw new AppException("数据项验证出错. Name=" + field.getName() + "; Value=[" + value + "]");
                    }
                }
            }
        }
    }
}
